package com.hongxun.design.utils.projectdatautil;

import java.math.BigDecimal;

public class PointUtil {
	private static double EARTH_RADIUS = (6378137+6356752.3142)/2;
	private static double rad(double d)
	{
		return d * Math.PI / 180.0;
	}

	public static double GetDistance(BigDecimal lng1, BigDecimal lat1, BigDecimal lng2, BigDecimal lat2)
	{
		BigDecimal radLat1 = new BigDecimal(rad(lat1.doubleValue()));
		BigDecimal radLat2 = new BigDecimal(rad(lat2.doubleValue()));
		System.out.println(radLat2);
		BigDecimal a = radLat1.subtract(radLat2);

		BigDecimal b = new  BigDecimal(rad(lng1.doubleValue())).subtract(new BigDecimal(rad(lng2.doubleValue())));
		double s = 2 * Math.sin(Math.sqrt(Math.pow(Math.sin((a.divide(new BigDecimal(2)) ).doubleValue()), 2) +
				Math.cos(radLat1.doubleValue()) * Math.cos(radLat2.doubleValue()) * Math.pow(Math.sin(a.divide(new BigDecimal(2)).doubleValue()), 2)));
		s = s * EARTH_RADIUS;
		return s;
	}

//    static double M_PI = Math.PI;
//    public static double[] lonLat2Mercator(double lon,double lat)
//    {
//        double[] xy = new double[2];
//        double x = lon *20037508.342789/180;
//        double y = Math.log(Math.tan((90+lat)*M_PI/360))/(M_PI/180);
//        y = y *20037508.34789/180;
//        xy[0] = x;
//        xy[1] = y;
//        return xy;
//    }


	static double DEF_PI = 3.14159265359; // PI
	static double DEF_2PI= 6.28318530712; // 2*PI
	static double DEF_PI180= 0.01745329252; // PI/180.0
	static double DEF_R =6370693.5; // radius of earth
	//适用于近距离
	public static double GetShortDistance(double lon1, double lat1, double lon2, double lat2)
	{
		double ew1, ns1, ew2, ns2;
		double dx, dy, dew;
		double distance;
		// 角度转换为弧度
		ew1 = lon1 * DEF_PI180;
		ns1 = lat1 * DEF_PI180;
		ew2 = lon2 * DEF_PI180;
		ns2 = lat2 * DEF_PI180;
		// 经度差
		dew = ew1 - ew2;
		// 若跨东经和西经180 度，进行调整
		if (dew > DEF_PI)
			dew = DEF_2PI - dew;
		else if (dew < -DEF_PI)
			dew = DEF_2PI + dew;
		dx = DEF_R * Math.cos(ns1) * dew; // 东西方向长度(在纬度圈上的投影长度)
		dy = DEF_R * (ns1 - ns2); // 南北方向长度(在经度圈上的投影长度)
		// 勾股定理求斜边长
		distance = Math.sqrt(dx * dx + dy * dy);
		return distance;
	}
	//适用于远距离
	public static double GetLongDistance(double lon1, double lat1, double lon2, double lat2)
	{
		double ew1, ns1, ew2, ns2;
		double distance;
		// 角度转换为弧度
		ew1 = lon1 * DEF_PI180;
		ns1 = lat1 * DEF_PI180;
		ew2 = lon2 * DEF_PI180;
		ns2 = lat2 * DEF_PI180;
		// 求大圆劣弧与球心所夹的角(弧度)
		distance = Math.sin(ns1) * Math.sin(ns2) + Math.cos(ns1) * Math.cos(ns2) * Math.cos(ew1 - ew2);
		// 调整到[-1..1]范围内，避免溢出
		if (distance > 1.0)
			distance = 1.0;
		else if (distance < -1.0)
			distance = -1.0;
		// 求大圆劣弧长度
		distance = DEF_R * Math.acos(distance);
		return distance;
	}
	/**
	 * 测试
	 *
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println(GetLongDistance(106.486654, 29.490295, 106.581515, 29.615467));
		System.out.println(GetShortDistance(106.486654, 29.490295, 106.581515, 29.615467));
	}
//	static double DEF_PI = 3.14159265359; // PI
//	static double DEF_2PI = 6.28318530712; // 2*PI
//	static double DEF_PI180 = 0.01745329252; // PI/180.0
//	static double DEF_R = 6370693.5; // radius of earth
//
//	/**
//	 * 使用户较长距离的档距计算
//	 * @param lon1   第一个点的经度数据
//	 * @param lat1   第一个点的纬度数据
//	 * @param lon2  第二个点的经度数据
//	 * @param lat2  第二个点的经度数据
//	 * @return
//	 */
//	public static double GetLongDistance(double lon1, double lat1, double lon2, double lat2) {
//		double ew1, ns1, ew2, ns2;
//		double distance;
//		// 角度数据转化为弧度数据
//		ew1 = lon1 * DEF_PI180;
//		ns1 = lat1 * DEF_PI180;
//		ew2 = lon2 * DEF_PI180;
//		ns2 = lat2 * DEF_PI180;
//
//		 // 求大圆劣弧与球心所夹的角(弧度)
//		distance = Math.sin(ns1) * Math.sin(ns2) + Math.cos(ns1) * Math.cos(ns2) * Math.cos(ew1 - ew2);
//
//		// 调整到[-1..1]范围内，避免溢出
//		if (distance > 1.0)
//			distance = 1.0;
//		else if (distance < -1.0)
//			distance = -1.0;
//
//		// 距离计算
//		distance = DEF_R * Math.acos(distance);
//		return distance;
//	}
//
//	/**
//	 * 测试
//	 *
//	 * @param args
//	 */
//	public static void main(String[] args) {
//		System.out.println(GetLongDistance(106.486654, 29.490295, 106.581515, 29.615467));
//	}

}
